#include "stm32f1xx_hal.h"
#include "rtc.h"
#include <stdio.h>
#include "timestamp_converter.h"


// 判断闰年
static uint8_t isLeapYear(uint16_t year) {
  return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}

// 获取指定月份的天数
static uint8_t getDaysInMonth(uint16_t year, uint8_t month) {
    if (month == 2) {
        return isLeapYear(year) ? 29 : 28;
    }
    return daysInMonth[month - 1];
}

// 获取当前时间戳（直接返回RTC对应的Unix时间戳）
uint32_t getCurrentTimestamp(void) {
  RTC_TimeTypeDef sTime;
  RTC_DateTypeDef sDate;
  
  HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
  HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
  
  // 计算从1970年到当前RTC时间的总秒数（Unix时间戳）
  uint16_t current_year = sDate.Year + 2000;  // RTC年份转换为实际年份
  uint32_t total_days = 0;
  
  // 累加1970年到当前年份的天数
  for (uint16_t y = 1970; y < current_year; y++) {
    total_days += isLeapYear(y) ? 366 : 365;
  }
  
  // 累加当前年份到当月的天数
  for (uint8_t m = 1; m < sDate.Month; m++) {
    total_days += getDaysInMonth(current_year, m);
  }
  
  // 累加当前日、时、分、秒
  total_days += (sDate.Date - 1);  // 当月已过的天数（日期-1）
  return total_days * 86400 + sTime.Hours * 3600 + sTime.Minutes * 60 + sTime.Seconds;
}

// 将UTC时间戳转换为北京时间（UTC+8）
void timestampToDateTime(uint32_t utc_timestamp, DateTimeTypeDef *dateTime) {
  // 关键：添加8小时时区偏移（8*3600=28800秒）
  uint32_t beijing_timestamp = utc_timestamp + 28800/2;
  
  dateTime->year = 1970;
  dateTime->month = 1;
  dateTime->day = 1;
  dateTime->hour = 0;
  dateTime->minute = 0;
  dateTime->second = 0;
  
  // 基于带时区偏移的时间戳计算
  uint32_t days = beijing_timestamp / 86400;
  uint32_t seconds = beijing_timestamp % 86400;
  
  // 计算时分秒（已包含时区偏移）
  dateTime->hour = seconds / 3600;
  seconds %= 3600;
  dateTime->minute = seconds / 60;
  dateTime->second = seconds % 60;
  
  // 计算年月日（基于1970年基准）
  while (days > 0) {
    uint16_t year_days = isLeapYear(dateTime->year) ? 366 : 365;
    if (days >= year_days) {
      days -= year_days;
      dateTime->year++;
    } else {
      while (days > 0) {
        uint8_t month_days = getDaysInMonth(dateTime->year, dateTime->month);
        if (days >= month_days) {
          days -= month_days;
          dateTime->month++;
          if (dateTime->month > 12) {
            dateTime->month = 1;
            dateTime->year++;
          }
        } else {
          dateTime->day += days;
          days = 0;
        }
      }
    }
  }
  
  dateTime->timestamp = utc_timestamp;  // 保留原始UTC时间戳（可选）
}

// 初始化基准时间（无需依赖RTC初始值，直接使用1970年基准）
void initBaseDateTime(void) {
  // 清空基准时间，改用1970年为基准
  baseDateTime.year = 1970;
  baseDateTime.month = 1;
  baseDateTime.day = 1;
  baseDateTime.hour = 0;
  baseDateTime.minute = 0;
  baseDateTime.second = 0;
  baseDateTime.timestamp = 0;
}

// 修改：适配简化版RTC结构体的时间设置函数
static HAL_StatusTypeDef setRTCTime(uint16_t year, uint8_t month, uint8_t day, 
                                   uint8_t hour, uint8_t minute, uint8_t second) {
  RTC_TimeTypeDef sTime = {0};
  RTC_DateTypeDef sDate = {0};
  
  // 简化版RTC_TimeTypeDef仅包含时分秒（24小时制）
  sTime.Hours = hour;       // 0-23
  sTime.Minutes = minute;   // 0-59
  sTime.Seconds = second;   // 0-59
  
  // 直接设置时间（无需TimeFormat等成员）
  if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK) {
    return HAL_ERROR;
  }
  
  // 设置日期
  sDate.Year = year - 2000;  // 相对于2000年的偏移
  sDate.Month = month;       // 1-12
  sDate.Date = day;          // 1-31
  sDate.WeekDay = RTC_WEEKDAY_MONDAY;  // 星期可忽略或简单设置
  
  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK) {
    return HAL_ERROR;
  }
  
  return HAL_OK;
}

// 通过时间戳设置RTC时间
HAL_StatusTypeDef setTimestamp(uint32_t targetTimestamp) {
  DateTimeTypeDef targetTime;
  timestampToDateTime(targetTimestamp, &targetTime);
  
  baseDateTime = targetTime;
  baseDateTime.timestamp = targetTimestamp;
  
  return setRTCTime(targetTime.year, targetTime.month, targetTime.day,
                   targetTime.hour, targetTime.minute, targetTime.second);
}

// 使用示例（移除中文，避免编码警告）
void exampleUsage() {
  initBaseDateTime();
  
  uint32_t currentTimestamp = getCurrentTimestamp();
  printf("Current timestamp: %lu\n", currentTimestamp);
  
  DateTimeTypeDef currentTime;
  timestampToDateTime(currentTimestamp, &currentTime);
  printf("Current time: %04d-%02d-%02d %02d:%02d:%02d\n",
         currentTime.year, currentTime.month, currentTime.day,
         currentTime.hour, currentTime.minute, currentTime.second);
  
  // 设置新的时间戳（例如：2024年1月1日 12:00:00，相对于2023年1月1日0点的秒数）
  uint32_t newTimestamp = 31536000;  
  if (setTimestamp(newTimestamp) == HAL_OK) {
    printf("Timestamp set successfully\n");
    
    currentTimestamp = getCurrentTimestamp();
    timestampToDateTime(currentTimestamp, &currentTime);
    printf("New time: %04d-%02d-%02d %02d:%02d:%02d\n",
           currentTime.year, currentTime.month, currentTime.day,
           currentTime.hour, currentTime.minute, currentTime.second);
  } else {
    printf("Failed to set timestamp\n");
  }
}